/* eslint-disable indent */
const fse = require('fs-extra');
const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const FilterWarningsPlugin = require('webpack-filter-warnings-plugin');
const SimpleProgressPlugin = require('webpack-simple-progress-plugin');
const ProgressPlugin = require('webpack/lib/ProgressPlugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const getFaviconPath = require('../utils/getFaviconPath');
const { appFaviconIco, appFavicon, appPublic, defaultAppHtml, defaultBuildPath, appPackageJson } = require('./paths');
const packageContent = require(appPackageJson);

module.exports = (chainConfig, mode = 'development') => {
  const rootDirPath = process.cwd();
  const projectConfigPath = path.join(rootDirPath, 'project.config.json');
  const RUN_ENV = typeof process.env.RUN_ENV === 'string' && process.env.RUN_ENV.charAt(0) === '{' ? eval(`(${process.env.RUN_ENV})`) : typeof process.env.RUN_ENV === 'object' && !Array.isArray(process.env.RUN_ENV) ? process.env.RUN_ENV : {};
  let projectConfigData = Object.assign({}, RUN_ENV);
  if (fse.existsSync(projectConfigPath)) {
    const projectConfigs = require(projectConfigPath);
    // 需要注入至项目里面的环境变量数据
    if (projectConfigs.projectConfig) {
      projectConfigData = Object.assign({}, projectConfigs.projectConfig, projectConfigData);
    }
  }

  const defineVariables = {
    'process.env.NODE_ENV': JSON.stringify(mode || 'development'),
    'process.projectConfig': JSON.stringify(projectConfigData)
  };

  projectConfigData.templateParameters = projectConfigData.templateParameters || {};

  chainConfig
    .plugin('DefinePlugin')
    .use(webpack.DefinePlugin, [defineVariables])
    .end()
    .plugin('MiniCssExtractPlugin')
    .use(MiniCssExtractPlugin, [{
      filename: `[name]${getVersion()}.css`,
    }])
    .end()
    .plugin('FilterWarningsPlugin')
    .use(FilterWarningsPlugin, [{
      exclude: /Conflicting order between:/,
    }])
    .end()
    .plugin('SimpleProgressPlugin')
    // SimpleProgressPlugin will not write webpack info to stderr when it is not tty
    .use(!process.stderr.isTTY ? ProgressPlugin : SimpleProgressPlugin)
    .end()
    .plugin('CaseSensitivePathsPlugin')
    .use(CaseSensitivePathsPlugin)
    .end()
    .plugin('HtmlWebpackPlugin')
    .use(HtmlWebpackPlugin, [{
      inject: true,
      templateParameters: {
        NODE_ENV: process.env.NODE_ENV,
        ...projectConfigData.templateParameters
      },
      meta: projectConfigData.templateParameters.meta || {},
      title: projectConfigData.templateParameters.title,
      favicon: getFaviconPath([appFaviconIco, appFavicon]),
      template: defaultAppHtml,
      minify: false,
    }])
    .end()
    .plugin('CopyWebpackPlugin') // 默认将 public/ 目录下的文件复制到 build/ 目录下
    .use(CopyWebpackPlugin, [[
      {
        from: appPublic,
        to: defaultBuildPath,
        ignore: ['index.html'],
      },
    ]]);
};

function getVersion(){
  let verNo = '';
  const fv = packageContent['file-version'];

  if(fv==='version'){
    verNo = `_v${packageContent.version}`;
  }else if(fv==='date'){
    const now = new Date();
    const fill0 = v => `0${v}`.slice(-2);
    verNo = `_d${now.getFullYear()+fill0(now.getMonth()+1)+fill0(now.getDate())}`;
  }else if(fv==='time'){
    verNo = `_t${Date.now()}`;
  }
  return verNo;
}